/**
 * @Description: 读取excel 文件
 *
 * @author: 风信子
 *
 * @date: 2021/3/3
 */

import * as SheetXlsx from "xlsx"; // 引入xlsx

export default class EXcelXlsx {
  // eslint-disable-next-line no-useless-constructor,no-empty-function
  constructor() {}

  /**
   * @date: 2021/3/3
   * @author 风信子
   * @Description: 方法说明  读取
   *
   * @method 方法名
   * @param {参数类型} 参数名 参数说明
   * @return {返回值类型} 返回值说明
   */
  outputWorkbook(workbook, type) {
    const sheetNames = workbook.SheetNames; // 工作表名称集合
    return sheetNames.map((item, index) => {
      const SheetsItem = workbook.Sheets[item]; // 单个sheet页数据
      // 处理日期格式展示问题
      for (const i in SheetsItem) {
        if (SheetsItem[i].z && SheetsItem[i].z === "m/d/yy") {
          const formatDate = this.formatDate(
            parseInt(SheetsItem[i].v, 10),
            "/"
          );
          SheetsItem[i].v = formatDate;
          SheetsItem[i].w = formatDate;
          // SheetsItem[i].t = "s";
        }
      }
      let workbookData = null; // 工作中表数据
      // 判断是否为空内容 空内容为 undefined
      if (SheetsItem["!ref"]) {
        if (type.toUpperCase() === "HTML") {
          workbookData = SheetXlsx.utils.sheet_to_html(workbook.Sheets[item]);
        } else if (type.toUpperCase() === "JSON") {
          workbookData = SheetXlsx.utils.sheet_to_json(workbook.Sheets[item], {
            header: "A",
          });
        } else {
          throw new Error("error in type");
        }
      }
      return {
        id: `shellId${index}`,
        name: item,
        sheetRange: SheetsItem["!ref"],
        workbookData,
      };
    });
  }

  /**
   * @date: 2021/3/3
   * @author 风信子
   * @Description: 方法说明 读取文件
   * @method 方法名 readFile
   * @param {string } 参数名 url 参数说明  文件地址
   * @param {string } 参数名 type 参数说明 转换类型  html,json  默认 html  文件地址
   * @param {boolean} filter  是否过滤空 sheet 页  默认过滤
   */
  async readFile(url = "", filter = true, type = "html") {
    const workbook = await this.httpRequest(url);
    // 判断是否过滤空表数据
    if (filter) {
      return this.outputWorkbook(workbook, type).filter(
        (item) => item.workbookData
      );
    }
    return this.outputWorkbook(workbook, type);
  }

  /**
   * @date: 2021/3/3
   * @author 风信子
   * @Description: 方法说明  获取网络文件流
   * @method 方法名 httpRequest
   * @param url
   */
  // eslint-disable-next-line class-methods-use-this
  httpRequest(url) {
    if (typeof url === "string" && url !== "") {
      // 根据文件路径来展示
      return new Promise((resolve) => {
        const xhr = new XMLHttpRequest();
        xhr.open("get", url, true);
        xhr.responseType = "arraybuffer";
        xhr.onload = function () {
          if (xhr.status === 200) {
            const data = new Uint8Array(xhr.response);
            const workbook = SheetXlsx.read(data, {
              type: "array",
              cellStyles: true,
              sheetStubs: true,
            });
            resolve(workbook);
          } else {
            // 根据文件流来展示
            const workbook = SheetXlsx.read(url, { type: "binary" });
            resolve(workbook);
          }
        };
        xhr.send();
      });
    }

    if (url.toString() === "[object File]") {
      // 上传的格式是文件类型
      return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onloadend = function (event) {
          const { result } = event.target;
          const workbook = SheetXlsx.read(result, {
            type: "array",
            cellStyles: true,
            sheetStubs: true,
          });
          resolve(workbook);
        };
        reader.readAsArrayBuffer(url);
      });
    }
    throw new Error("url is null or not a string or file");
  }

  // excel读取2018/01/01这种时间格式是会将它装换成数字类似于46254.1545151415 numb是传过来的整数数字，format是之间间隔的符号
  formatDate(numb, format) {
    const time = new Date((numb - 1) * 24 * 3600000 + 1);
    time.setYear(time.getFullYear() - 70);
    const year = `${time.getFullYear()}`;
    const month = `${time.getMonth() + 1}`;
    const date = `${time.getDate() - 1}`;
    if (format && format.length === 1) {
      return year + format + month + format + date;
    }
    return (
      year +
      (month < 10 ? `0${month}` : month) +
      (date < 10 ? `0${date}` : date)
    );
  }
}
